import { Sequelize } from "sequelize";
import { Application } from "egg";

/**
 * Sequelize数据库连接配置
 */
export default class SequelizeService {
  private app: Application;
  private sequelize: Sequelize | null = null;

  constructor(app: Application) {
    this.app = app;
  }

  /**
   * 初始化Sequelize连接
   */
  public async init(): Promise<Sequelize> {
    if (this.sequelize) {
      return this.sequelize;
    }

    const { config, logger } = this.app;
    const dbConfig = config.mysql.client;

    try {
      // 创建Sequelize实例
      this.sequelize = new Sequelize({
        database: dbConfig.database,
        username: dbConfig.user,
        password: dbConfig.password,
        host: dbConfig.host,
        port: parseInt(dbConfig.port as string),
        dialect: "mysql",
        dialectModule: require("mysql2"),

        // 连接池配置
        pool: {
          max: 10,
          min: 0,
          acquire: 30000,
          idle: 10000
        },

        // 字符集配置
        dialectOptions: {
          charset: "utf8mb4",
          collate: "utf8mb4_unicode_ci",
          supportBigNumbers: true,
          bigNumberStrings: true,
          // MySQL 8.0 认证协议
          authPlugins: {
            mysql_native_password: () => require("mysql2/lib/auth_plugins").mysql_native_password
          }
        },

        // 日志配置
        logging: (sql: string) => {
          logger.info("[Sequelize SQL]", sql);
        },

        // 时区配置
        timezone: "+08:00",

        // 其他配置
        define: {
          timestamps: true,
          underscored: true,
          freezeTableName: true,
          charset: "utf8mb4",
          collate: "utf8mb4_unicode_ci"
        }
      });

      // 测试连接
      await this.sequelize.authenticate();
      logger.info("✅ Sequelize数据库连接成功");

      return this.sequelize;
    } catch (error) {
      logger.error("❌ Sequelize数据库连接失败:", error);
      throw error;
    }
  }

  /**
   * 获取Sequelize实例
   */
  public getSequelize(): Sequelize {
    if (!this.sequelize) {
      throw new Error("Sequelize未初始化，请先调用init()方法");
    }
    return this.sequelize;
  }

  /**
   * 同步数据库模型
   */
  public async syncModels(force = false): Promise<void> {
    if (!this.sequelize) {
      throw new Error("Sequelize未初始化");
    }

    try {
      await this.sequelize.sync({ force });
      this.app.logger.info("✅ 数据库模型同步完成");
    } catch (error) {
      this.app.logger.error("❌ 数据库模型同步失败:", error);
      throw error;
    }
  }

  /**
   * 关闭数据库连接
   */
  public async close(): Promise<void> {
    if (this.sequelize) {
      await this.sequelize.close();
      this.app.logger.info("🔒 Sequelize数据库连接已关闭");
      this.sequelize = null;
    }
  }
}
